home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / ColorWarp-c / ColorStars.c next >
Encoding:
Text File  |  1994-12-04  |  9.4 KB  |  401 lines  |  [TEXT/MMCC]

  1. //• PD color star warp program sent to me (Ken Long) by a programmer 
  2. //• on the net, on request.
  3. //• Pretty much generic and common (there are lots of warp programs).
  4. //• Hold down '+' to accelerate, '-' to decelerate, mouse turns, 'q'
  5. //• or click quits.
  6. //• Be sure to run this program in 1 bit mode, too!
  7. //• Add MacTraps and ASNI, and drop this file on Stuff It Expander
  8. //• to get the .rsrc file out of it.
  9.  
  10. //• el warpo.c
  11.  
  12. //• Uses direct screen access; 
  13. //• Needs Apple Macintosh with FPU (not!).  
  14. //• Works without FPU but very slow.
  15. //• Optimized for shipSpeed, not elegance.
  16.  
  17. //• TODO:
  18. //• Don't assume monitor is landscape.
  19. //• improve translation algorithm, use mathematically, graphically
  20. //•     correct algorithm.
  21. //• Use keyboard map.
  22. //• Use integer math?
  23. //• Improve separation of code for different screen depths.
  24. //• Make more structured, but keep code fast.
  25.  
  26. #include <math.h>
  27.  
  28. #ifndef powerc
  29.     #include <SANE.h>
  30. #endif
  31.  
  32. #include <Types.h>
  33. #include <Memory.h>
  34. #include <Quickdraw.h>
  35. #include <Fonts.h>
  36. #include <Events.h>
  37. #include <Menus.h>
  38. #include <Windows.h>
  39. #include <TextEdit.h>
  40. #include <Dialogs.h>
  41. #include <OSUtils.h>
  42.  
  43. #define num_stars 180    //• Reduce number for more speed (try 18).
  44.                         
  45. //• Apparent density of star field; number of 'close calls'.
  46. #define density 1            
  47.  
  48. #define max_distance 255    //• Index of last color in 8 bit clut.
  49. #define star_clut_ID 128
  50.  
  51. EventRecord            theEvent;
  52. Boolean                keep_going = true;
  53. RgnHandle            GrayRgn, mBarRgn;
  54. short                *mBarHeightPtr;
  55. short                oldMBarHeight;
  56. Rect                windowBounds;
  57. CWindowPtr            theWindow;
  58. short                H_far, V_far;
  59. double                star_H [num_stars] , star_V [num_stars] , distance [num_stars] ;
  60. double                shipSpeed;
  61.  
  62. void HireTheManagers (void);
  63. void HideMenuBar (void);
  64. void ShowMenuBar (void);
  65. void SetUpWindow (void);
  66. long double Randomize (short high);
  67. long double A_B (long double number);
  68. void LoadStars (void);
  69. void HandleEvent (void);
  70. void MainlyLooping (void);
  71. int main (void);
  72.  
  73. void HireTheManagers (void) 
  74. {
  75.     MaxApplZone ();
  76.     InitGraf (&qd.thePort);
  77.     InitFonts ();
  78.     FlushEvents (everyEvent, 0);
  79.     InitWindows ();
  80.     InitMenus ();
  81.     TEInit ();
  82.     InitDialogs (0L);
  83.     InitCursor ();
  84.     MoreMasters ();
  85. }
  86.  
  87. void HideMenuBar (void) 
  88. {
  89.     Rect    mBarRect;
  90.  
  91.     GrayRgn = GetGrayRgn ();
  92.     mBarHeightPtr = (short *) 0x0BAA;
  93.     oldMBarHeight = *mBarHeightPtr;
  94.     *mBarHeightPtr = 0;
  95.     mBarRect = qd.screenBits.bounds;
  96.     mBarRect.bottom = mBarRect.top+oldMBarHeight;
  97.     mBarRgn = NewRgn ();
  98.     RectRgn (mBarRgn, &mBarRect);
  99.     UnionRgn (GrayRgn, mBarRgn, GrayRgn);
  100.     PaintOne (0L, mBarRgn);
  101. }
  102.  
  103. //• Show me the way to the next Whiskey bar.
  104. void ShowMenuBar (void)    
  105. {
  106.     *mBarHeightPtr = oldMBarHeight;
  107.     DiffRgn (GrayRgn, mBarRgn, GrayRgn);
  108.     DisposeRgn (mBarRgn);
  109. }
  110.  
  111. void SetUpWindow (void) 
  112. {
  113.     short    centerx, centery;
  114.  
  115.     windowBounds = qd.screenBits.bounds;
  116.     theWindow = (CWindowPtr)NewCWindow (0L, &windowBounds, "\pNameless", true, 
  117.                             (short)plainDBox, (WindowPtr)-1L, true, (long)0);
  118.     SetPort ((GrafPtr)theWindow);
  119.     InvertRect (&windowBounds);
  120.     centerx = - (windowBounds.right/2);
  121.     centery = - (windowBounds.bottom/2);
  122.     SetOrigin (centerx, centery);
  123.     H_far = windowBounds.right/2;
  124.     V_far = windowBounds.bottom/2;
  125. }
  126.  
  127. long double Randomize (short high)
  128. {
  129.     long double    rawResult;
  130.  
  131.     rawResult = Random ();
  132.     return ((rawResult * high) / 32768);
  133. }
  134.  
  135. long double A_B (long double number)
  136. {
  137.     if (number < 0) 
  138.     return - number;
  139.         else
  140.     return number;
  141. }
  142.  
  143. void LoadStars (void)        //• Could amount to trillions of tons!
  144. {
  145.     short    i;
  146.  
  147.     for (i = 0; i < num_stars; i++) 
  148.     {
  149.         star_H [i] = Randomize (H_far);
  150.         star_V [i] = Randomize (V_far);
  151.         distance [i] = Randomize (max_distance);
  152.     }
  153. }
  154.  
  155. void HandleEvent () 
  156. {
  157.     char    theChar;
  158.  
  159.     switch (theEvent.what) 
  160.     {
  161.         case mouseDown:
  162.             keep_going = FALSE;
  163.         break;
  164.         
  165.         case keyDown:
  166.         case autoKey:
  167.             theChar = (theEvent.message & charCodeMask);
  168.             if ((theChar == '=')||(theChar == '+')) 
  169.                 shipSpeed += 0.5;
  170.             if ((theChar == '-')||(theChar == '_')) 
  171.                 shipSpeed -= 0.5;
  172.             if ((theChar == 'q')||(theChar == 'Q')) 
  173.                 keep_going = FALSE;
  174.         break;
  175.             
  176.         default:
  177.         break;
  178.     }
  179. }
  180.  
  181. void MainlyLooping (void)        //• Loop 'til you poop!
  182. {
  183.     Point mouseLoc;
  184.     short A_B_H, A_B_V;
  185.     short dark, gray, x_edge, y_edge, diagonal, j, k;
  186.     double mx, my, tempx, tempy, temp, sin_rotate, cos_rotate;
  187.     register short i;
  188.     
  189.     //• graphics vars
  190.     GDHandle        theGDevice;
  191.     PixMapHandle    thePixMap;
  192.     unsigned char *drawAddr;
  193.     unsigned char *baseAddr;
  194.     unsigned long rowBytes;
  195.     short            depth;
  196.     Size            mapSize;
  197.     unsigned char mask;
  198.     CTabHandle        starclut;
  199.  
  200.     //• initial settings.
  201.     LoadStars ();
  202.     
  203.     SetEventMask (mDownMask + keyDownMask + autoKeyMask);
  204.     shipSpeed = 2;
  205.     diagonal = (short) sqrt (((long double) H_far * H_far) + 
  206.                          ((long double) V_far * V_far));
  207.     x_edge = H_far - 10;
  208.     y_edge = V_far - 10;
  209.     
  210.     H_far -= 2;
  211.     V_far -= 2;
  212.  
  213.     //• get info about current device to be drawn to.
  214.     theGDevice = GetGDevice ();
  215.     thePixMap = (*theGDevice) ->gdPMap;
  216.     baseAddr = (unsigned char *)(*thePixMap) ->baseAddr;
  217.     rowBytes = (unsigned long)  ((*thePixMap) ->rowBytes & 0x3FFF);
  218.     depth = (*thePixMap) ->pixelSize;
  219.     mapSize = rowBytes*qd.screenBits.bounds.bottom;
  220.  
  221.     //• set color table to star grays if device is 8 bit.
  222.     if (depth == 8) 
  223.     {
  224.             starclut = (CTabHandle)GetResource ('clut', star_clut_ID);
  225.             SetEntries (-1, ((*starclut)->ctSize) +1, (*starclut)->ctTable);
  226.     }
  227.  
  228.     if (depth != 8 && depth != 1) 
  229.         keep_going = false;
  230.  
  231.     //• main loop.
  232.     while (keep_going == true) 
  233.     {
  234.         //• handle user input.
  235.         if (GetNextEvent (everyEvent, &theEvent)) 
  236.             HandleEvent ();
  237.             GetMouse (&mouseLoc);
  238.             mx = ((double) mouseLoc.h / 420);
  239.             if (A_B (mouseLoc.h) < 2) 
  240.                 mx = 0;
  241.                 my = ((double) mouseLoc.v / 8);
  242.                 sin_rotate = sin (mx);
  243.                 cos_rotate = cos (mx);
  244.     
  245.                 //• cycle through list of stars.
  246.                 for (i = 0; i < num_stars; i++) 
  247.                 {
  248.                     A_B_H = star_H [i] + H_far;
  249.                     A_B_V = star_V [i] + V_far;
  250.                 
  251.                     //• erase star
  252.                     if ((A_B (star_V [i]) <V_far) && (A_B (star_H [i]) <H_far)) 
  253.                     {
  254.                         switch (depth) 
  255.                         {
  256.                             case 1:
  257.                                 drawAddr = baseAddr+ (A_B_V * rowBytes + A_B_H/8L);
  258.                                 mask = (unsigned char) 1 << (7- (A_B_H% 8));
  259.                                 *drawAddr |= mask;
  260.                             break;
  261.                             
  262.                             case 8:
  263.                                 drawAddr = baseAddr+A_B_V * 
  264.                                          rowBytes + A_B_H;
  265.                                 for (j = 1; j <= 3; j++) 
  266.                                 {
  267.                                     for (k = 1; k <= 3; k++) 
  268.                                     {
  269.                                         *drawAddr = 0xFF;
  270.                                         drawAddr++;
  271.                                     }
  272.                                     drawAddr -= 3;
  273.                                     drawAddr += rowBytes;
  274.                                 }
  275.                             break;
  276.                             default:
  277.                             break;
  278.                         }
  279.                     }
  280.                                 
  281.                     //• update star's mapped projection.
  282.                     temp = (density + shipSpeed + distance [i]) / 
  283.                            (distance [i] + density);
  284.                          
  285.                     star_H [i] = star_H [i] *temp;
  286.                     star_V [i] = star_V [i] *temp + my;
  287.                     temp = star_H [i] ;
  288.                     
  289.                     star_H [i] = star_H [i] *cos_rotate + 
  290.                                  star_V [i] *sin_rotate;
  291.                                  
  292.                     star_V [i] = -temp * sin_rotate + star_V [i] * cos_rotate;
  293.                     distance [i] -= shipSpeed;
  294.                 
  295.                     //• if offscreen or past, generate new star*/
  296.                     if ((A_B (star_H [i]) > diagonal) ||
  297.                          (A_B (star_V [i]) > diagonal) ||
  298.                          (distance [i] < 0) ||
  299.                          (distance [i] > max_distance)) 
  300.                     {
  301.                         if (shipSpeed > 0)     //• going forwards.
  302.                         {
  303.                             star_H [i] = Randomize (x_edge);
  304.                             star_V [i] = Randomize (y_edge) - my;
  305.                             distance [i] = max_distance;
  306.                         }
  307.                         else        //• going backwards (not finished).
  308.                             {
  309.                                 if (Randomize (1) > 0) 
  310.                                 {
  311.                                     star_H [i] = Randomize (H_far);
  312.                                     if (Randomize (1) > 0) 
  313.                                         star_V [i] = V_far;
  314.                                     else
  315.                                         star_V [i] = -V_far;
  316.                                 }
  317.                                 else
  318.                                     {
  319.                                         star_V [i] = Randomize (V_far);
  320.                                         if (Randomize (1) < 0) 
  321.                                             star_H [i] = H_far;
  322.                                         else
  323.                                             star_H [i] =- H_far;
  324.                                 }
  325.                                 distance [i] = A_B (Randomize (max_distance - 20)) +20;
  326.                             }
  327.                         }
  328.                     
  329.                         //• redraw star at new position
  330.                         A_B_H = star_H [i] + H_far;
  331.                         A_B_V = star_V [i] + V_far;
  332.                         if ((A_B (star_V [i]) < V_far) && (A_B (star_H [i]) < H_far)) 
  333.                         {
  334.                             switch (depth) 
  335.                             {
  336.                                 case 1:
  337.                                     drawAddr = baseAddr + 
  338.                                               (A_B_V * 
  339.                                                rowBytes + 
  340.                                                A_B_H / 8L);
  341.                                                
  342.                                     mask = (unsigned char) 1 << 
  343.                                            (7 - (A_B_H % 8));
  344.                                            
  345.                                     *drawAddr ^= mask;
  346.                                 break;
  347.                                 
  348.                                 case 8:
  349.                                     dark = max_distance - 
  350.                                          ((max_distance - 
  351.                                            distance [i]) / 6);
  352.                                            
  353.                                     gray = max_distance - 
  354.                                          ((max_distance - 
  355.                                            distance [i]) / 4);
  356.                                            
  357.                                     drawAddr = baseAddr + 
  358.                                                A_B_V * 
  359.                                                rowBytes + 
  360.                                                A_B_H;
  361.                                                
  362.                                     *drawAddr = dark;
  363.                                     drawAddr++;
  364.                                     *drawAddr = gray;
  365.                                     drawAddr++;
  366.                                     *drawAddr = dark;
  367.                                     drawAddr += rowBytes - 2;
  368.                                     *drawAddr = gray;
  369.                                     drawAddr++;
  370.                                     *drawAddr = distance [i] ;
  371.                                     drawAddr++;
  372.                                     *drawAddr = gray;
  373.                                     drawAddr += rowBytes - 2;
  374.                                     *drawAddr = dark;
  375.                                     drawAddr++;
  376.                                     *drawAddr = gray;
  377.                                     drawAddr++;
  378.                                     *drawAddr = dark;
  379.                                 break;
  380.                                 
  381.                                 default:
  382.                                 break;
  383.                             }
  384.                         }
  385.                     }
  386.     }
  387.     SetEventMask (everyEvent);
  388. }
  389.  
  390. int main (void)
  391. {
  392.     HireTheManagers ();        //• These guys Macintize.
  393.     HideMenuBar ();            //• Get rid of this interference.
  394.     SetUpWindow ();            //• A place to draw.
  395.     HideCursor ();            //• Swat that fly!
  396.     MainlyLooping ();        //• Get yer mo jo workin'.
  397.     ShowCursor ();            //• Return of the Fly!
  398.     ShowMenuBar ();            //• Get ready for Finder's keepers.
  399. }
  400.  
  401.